package com.star.ms.admin.service.impl.user;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.star.ms.admin.service.user.RpService;
import com.star.ms.admin.service.user.UrService;
import com.star.ms.common.dao.mapper.user.RoleMapper;
import com.star.ms.common.dao.mapper.user.RpMapper;
import com.star.ms.common.dao.mapper.user.UrMapper;
import com.star.ms.admin.dao.impl.user.UserDAOImpl;
import com.star.ms.common.pojo.user.Perm;
import com.star.ms.common.pojo.user.Role;
import com.star.ms.admin.service.user.RoleService;
import com.star.ms.common.pojo.user.Rp;
import com.star.ms.common.pojo.user.Ur;
import com.star.ms.common.vo.RolePermVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author uni10
* @description 针对表【ms_role】的数据库操作Service实现
* @createDate 2022-05-22 13:29:22
*/
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role>
    implements RoleService {
    @Autowired
    private UserDAOImpl userDAO;
    @Autowired
    private UrMapper userRoleMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RpService rpService;
    @Autowired
    private UrService urService;

    @Override
    public boolean modifyUserRoleByCode(List<String> userIds, Integer roleId) {
        LambdaQueryWrapper<Ur> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Ur::getUserId, userIds);
        Ur userRole = new Ur();
        userRole.setRoleId(roleId);
        return userRoleMapper.update(userRole, wrapper) > 0;
    }

    @Override
    public Role getByUserCode(String userCode) {
        return roleMapper.selectByUserCode(userCode);
    }


    /**
     * 查找角色和权限
     * @param condition
     * @return
     */
    @Override
    public IPage<RolePermVo> getRoleWithPermsByCondition(Map<String, Object> condition) {
        int pageNum = 1;
        int pageSize = 5;
        if(condition != null){
            pageNum = Integer.parseInt(condition.getOrDefault("pageNum", 1).toString());
            pageSize = Integer.parseInt(condition.getOrDefault("pageSize", 5).toString());
        }
        IPage<Role> roleIPage = roleMapper.selectWithPermsByCondition(new Page<>(pageNum, pageSize), condition);
        List<RolePermVo> list = new ArrayList<>();

        for (Role role : roleIPage.getRecords()) {
            for (Perm perm : role.getPerms()) {
                RolePermVo rolePermVo = new RolePermVo();
                // 清除 role的perms
                role.setPerms(null);
                rolePermVo.setRole(role);
                rolePermVo.setPerm(perm);
                list.add(rolePermVo);
            }
        }
        IPage<RolePermVo> page = new Page<>();
        page.setRecords(list);
        page.setSize(roleIPage.getSize());
        page.setPages(roleIPage.getPages());
        page.setCurrent(roleIPage.getCurrent());
        page.setTotal(roleIPage.getTotal());
        return page;
    }

    @Override
    public boolean removeRolePerm(List<Integer> roleIds, List<Integer> permIds) {
        assert roleIds.size() == permIds.size() : "删除角色权限的ID不对应!";
        boolean result = true;
        for(int i = 0, n = roleIds.size(); i < n; i++){
            LambdaQueryWrapper<Rp> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Rp::getRoleId, roleIds.get(i));
            wrapper.eq(Rp::getPermId, permIds.get(i));
            result &= rpService.remove(wrapper);
        }
        return result;
    }

    @Override
    public boolean addRole(String roleName, Integer roleExtendsId) {
        Role insertRole = new Role();
        insertRole.setName(roleName);
        // 插入角色
        boolean flag = roleMapper.insert(insertRole) > 0;
        // 继承权限
        if(flag && roleExtendsId > 0){
            // 查询刚刚插入的角色
            LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Role::getName, roleName);
            Role role = this.getOne(wrapper);
            // 查询继承的角色权限列表
            LambdaQueryWrapper<Rp> rpWrapper = new LambdaQueryWrapper<>();
            rpWrapper.eq(Rp::getRoleId, roleExtendsId);
            List<Rp> rps = rpService.list(rpWrapper);
            // 取出继承角色拥有的权限ID
            List<Integer> pids = rps.stream().map(Rp::getPermId).collect(Collectors.toList());
            List<Rp> list = new ArrayList<>();
            for (Integer pid : pids) {
                Rp rp = new Rp();
                rp.setRoleId(role.getId());
                rp.setPermId(pid);
                list.add(rp);
            }
            // 插入权限
            flag = rpService.saveBatch(list) || rps.size() == 0;
        }
        return flag;
    }

    @Override
    public boolean removeRole(Integer roleId) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getId, roleId);
        // 将相关角色的用户改为普通会员的角色
        UpdateWrapper<Ur> urWrapper = new UpdateWrapper<>();
        urWrapper.eq("ur_role_id", roleId).set("ur_role_id", 2);
        urService.update(urWrapper);
        return this.remove(wrapper);
    }

    @Override
    public boolean addPerm(Integer roleId, Integer permId) {
        Rp rp = new Rp();
        rp.setPermId(permId);
        rp.setRoleId(roleId);
        return rpService.save(rp);
    }
}




